package phoenixAAD.WifiFlashDrive;

import java.io.IOException;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

public class FTP extends Service {	
	// public variables for message passing
	public static final String MESSENGER = "MESSENGER",
			PORT = "PORT",
			INTENT_ROOT = "ROOT",
			COMPATIBILITY = "COMPATIBILITY";
	public static final int 
			LOG = 0,
			CLIENT_LOG = 1,
			SERVER_LOG = 2,
			SERVER_INIT_ERROR = 3,
			SERVER_EXCEPTION = 4,
			PROGRESS_BAR = 5,
			INDETERMINATE_PROGRESS = 6;
	
	public static final String UTF = "UTF-8", SHIFT_JIS = "Shift-JIS";
	
	// private variables
	private static boolean isOnline = false;
	private static int port = 0;
	private final Object SERVER_LOCK = new Object(); // for synchronization of on/off of server
	
	
	private static Messenger activityMessenger = null;
	
	private static Server server;
	public String rootDirectory = "";
	private NotificationManager mNotificationManager;
	private Notification notification;
	
	private static boolean sending = false, receiving = false;
	private static CharSequence tickerText, contentText, contentTitle;

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		synchronized(SERVER_LOCK)
		{
			String ns = Context.NOTIFICATION_SERVICE;
			mNotificationManager = (NotificationManager) getSystemService(ns);
			tickerText = getResources().getString(R.string.notification_ticker);
			contentText = getResources().getString(R.string.notification_text);
			contentTitle = getString(R.string.app_name);
			Log.d("Server",  "starting");
			if(intent != null)
			{
				activityMessenger = (Messenger) intent.getExtras().get(MESSENGER);
				
				if(isOnline)
				{					
					sendLog(getString(R.string.server_running));
				}
				else
				{
					port = intent.getIntExtra(PORT, -1);
					
					try {
						rootDirectory = intent.getStringExtra(INTENT_ROOT);
						if(intent.getBooleanExtra(COMPATIBILITY, false))
							server = new Server(port, rootDirectory, this, SHIFT_JIS);
						else
							server = new Server(port, rootDirectory, this, UTF);
						server.setUsername(intent.getStringExtra("username"));
						server.setPassword(intent.getStringExtra("password"));
						server.start();
						isOnline = true;
						sendLog(getString(R.string.server_started));
						sendNotification();
					} catch (IOException e) {
						e.printStackTrace();
						Message sendMessage = Message.obtain();
						sendMessage.arg1 = SERVER_INIT_ERROR;
						try {
							activityMessenger.send(sendMessage);
						} catch (RemoteException e1) {
						}
					}
					
					
				}		
			}
		}
		
		return Service.START_STICKY;
	}
	
	@Override
	public void onDestroy() {
		synchronized(SERVER_LOCK)
		{
			Log.d("Server", "stopping");
			isOnline = false;
			
			if(server != null)
			{
				server.close();
				try {
					server.join();
				} catch (InterruptedException e) {
					Log.d("Server", "interrupted");
				}
			}
			else
				Log.d("FTP", "server was null");
			sendLog(getString(R.string.server_stopped));
			mNotificationManager.cancel(1);
		}
			
		Log.d("Server", "server stopped");
		super.onDestroy();
	}
	
	
	//=======================
	// static getters
	
	public static boolean isServerRunning()
	{
		return isOnline;
	}
	
	public static int getPort()
	{
		return port;
	}
	
	/**
	 * gets the messenger to the activity, may return null
	 */
	public static Messenger getMessenger()
	{
		return activityMessenger;
	}
	
	/**
	 * Replaces the messenger to a new messenger
	 */
	public static void setMessenger(Messenger messenger)
	{
		activityMessenger = messenger;
	}
	//=========================
	// helpers

	/**
	 * Sends message to the activity to show on the log 
	 * @param message - string to print to log
	 */
	public void sendLog(String message)
	{
		Message send_Message = Message.obtain();
		send_Message.what = LOG;
		send_Message.obj = message;
		if(activityMessenger != null)
			try {
				activityMessenger.send(send_Message);
			} catch (RemoteException e) {}
	}
	
	/**
	 * Sends server's message to the activity to show on the log 
	 * @param message - string to print to log
	 */
	public void sendServerLog(String message)
	{
		Message send_Message = Message.obtain();
		send_Message.what = SERVER_LOG;
		send_Message.obj = message;
		if(activityMessenger != null)
			try {
				activityMessenger.send(send_Message);
			} catch (RemoteException e) {}
	}
	
	/**
	 * Sends client's message to the activity to show on the log 
	 * @param message - string to print to log
	 */
	public void sendClientLog(String message)
	{
		Message send_Message = Message.obtain();
		send_Message.what = CLIENT_LOG;
		send_Message.obj = message;
		if(activityMessenger != null)
			try {
				activityMessenger.send(send_Message);
			} catch (RemoteException e) {}
	}
	
	/**
	 * Sends the server's progress to the activity to update progress bar.
	 * @param status - status of the transfer 
	 */	
	public void sendProgressStatus(int status){
		if(status < 0 || status >= 100)
		{
			sending = false;
			sendNotification();
		}
		else if(!sending)
		{
			sending = true;
			sendNotification();
		}
		Message send_message = Message.obtain();
		send_message.what = PROGRESS_BAR;
		send_message.obj = status;
		if(activityMessenger != null){
			try {
				activityMessenger.send(send_message);
			} catch (RemoteException e) {}
		}
	}
	
	/**
	 * Sends the server's progress to the activity to show an indeterminate progress bar<br>
	 * Use this for receiving unknown amount of data
	 * @param isRunning
	 */
	public void sendIndeterminate(boolean isRunning){
		Log.d("ftp", "send indeterminate");
		receiving = isRunning;
		sendNotification();
		Message send_message = Message.obtain();
		send_message.what = INDETERMINATE_PROGRESS;
		send_message.obj = isRunning;
		if(activityMessenger != null){
			try {
				activityMessenger.send(send_message);
			} catch (RemoteException e) {}
		}
	}
	

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}


	private void sendNotification() {	
		if(isOnline)
		{
			int icon;
			if(sending && receiving)
				icon = R.drawable.status_both;
			else if (sending)
				icon = R.drawable.status_up;
			else if (receiving)
				icon = R.drawable.status_down;
			else
				icon = R.drawable.status_off;
			long when = System.currentTimeMillis();
			notification = new Notification(icon, tickerText, when);
			
			Context context = getApplicationContext();
			Intent notificationIntent = new Intent(this, WiFiFlashDriveActivity.class);
			PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
	
			notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
			mNotificationManager.notify(1, notification);
		}
	}
	
	public static boolean isTransferring()
	{
		if(server == null)
			return false;
		return server.isTransferring();
	}
	
	public static void close()
	{
		
	}
}
